﻿using System;
using System.Linq.Expressions;
using System.Reflection;

namespace Microsoft.Reflection
{
    public static class PropertySupportExtensions
    {
        public static String ExtractPropertyName<T>(this Expression<Func<T>> propertyExpression)
        {
            var memberInfo = propertyExpression.ExtractMemberInfo();
            memberInfo.ToPropertyInfo();           
            return memberInfo.Name;
        }

        public static MemberInfo ExtractMemberInfo<T>(this Expression<Func<T>> propertyExpression)
        {
            if (propertyExpression == null)
                throw new ArgumentNullException("propertyExpression");
            
            var memberExpression = propertyExpression.Body as MemberExpression;
            if (memberExpression == null)
                throw new ArgumentException("The expression is not a member access expression.");
      
            return memberExpression.Member;
        }

        public static PropertyInfo ExtractPropertyInfo<T>(this Expression<Func<T>> propertyExpression)
        {
            var memberInfo = propertyExpression.ExtractMemberInfo();
            return memberInfo.ToPropertyInfo();
        }

        static PropertyInfo ToPropertyInfo(this MemberInfo memberInfo)
        {
            var property = memberInfo as PropertyInfo;
            if (property == null)
                throw new ArgumentException("The member access expression does not access a property.");
   
            var getMethod = property.GetMethod;
            if (getMethod.IsStatic)
                throw new ArgumentException("The referenced property is a static property.");
            
            return property;
            
        }
    }
}